package com.jfs.envent.listener;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jfs.cmd.SIPCommander;
import com.jfs.entity.Device;
import com.jfs.envent.entity.DeviceOnlineEventEntity;
import com.jfs.health.RegistryDevice;
import com.jfs.service.DeviceService;
import com.jfs.utils.DeviceUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;


/**
 * @Description 设备上线监听器
 * @E-mail cwm3412638@163.com
 * @Author cwm
 * @Date 2022/8/1
 */
@Component
@Slf4j
@AllArgsConstructor
public class DeviceOnlineEventListener implements ApplicationListener<DeviceOnlineEventEntity> {
    private final SIPCommander sipCommander;
    private final DeviceService deviceService;
    /**
     * 防止多线程情况下 设备注册 设备id主键冲突问题
     */
    private final static ReentrantLock LOCK = new ReentrantLock(true);

    @Override
    @Async
    public void onApplicationEvent(DeviceOnlineEventEntity event) {
        try {
            if (log.isDebugEnabled()) {
                log.debug("【设备号:{},设备ip:{},设备端口号:{}】，设备上线：{}", event.getDeviceID(), event.getIp(), event.getPort(), JSONUtil.toJsonStr(event));
            }
            //1.注册设备到注册表中
            RegistryDevice.registry(DeviceUtil.createBaseDevice(event));
            // 2.从数据库中查询设备信息
            LOCK.lock();
            Device device = this.deviceService.getOne(Wrappers.<Device>lambdaQuery().eq(Device::getDeviceId, event.getDeviceID()));
            if (Objects.isNull(device)) {
                save(event);
            } else {
                //更新设备注册信息
                updateDevice(event);
            }
            // 4.设备注册成功查询设备信息
            sipCommander.deviceInfo(event.getRequestEvent());
            // 5.设备目录信息查询请求
            sipCommander.catalog(event.getRequestEvent());
            //6.查询设备配置信息
            sipCommander.configDownload(event.getRequestEvent());

        } catch (Exception e) {
            log.error("设备上线事件发生异常:{}", e.getMessage());
            e.printStackTrace();
        } finally {
            LOCK.unlock();
        }
    }


    private void updateDevice(DeviceOnlineEventEntity event) {
        DateTime now = DateUtil.date();
        this.deviceService.update(Wrappers.<Device>lambdaUpdate()
                .set(Device::getOnline, true)
                .set(Device::getRegisterTime, now)
                .set(Device::getUpdateTime, now)
                .eq(Device::getDeviceId, event.getDeviceID()));
    }


    private void save(DeviceOnlineEventEntity event) {
        Device baseDevice = DeviceUtil.createBaseDevice(event);
        this.deviceService.save(baseDevice);
    }
}
